package com.googlecode.imanager.client.style;

import java.io.Serializable;

import com.googlecode.imanager.client.bridge.style.IStyle;
import com.googlecode.imanager.client.style.listener.StyleAttribute;
import com.googlecode.imanager.client.style.listener.StyleListener;
import com.googlecode.imanager.client.util.Utils;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class Style implements IStyle, Serializable, Cloneable {

    private static final long serialVersionUID = 1L;
    
    private StyleListener listener;

    private Font font;
    private Border borderLeft;
    private Border borderTop;
    private Border borderRight;
    private Border borderBottom;
    private Background background;
    private Opacity opacity;

    public Style() {
        super();
    }

    public Style(Font font) {
        super();
        this.font = font;
    }

    public Style(Border border) {
        super();
        setBorder(border);
    }

    public Style(Background background) {
        super();
        this.background = background;
    }

    public Style(Font font, Border border) {
        super();
        this.font = font;
        setBorder(border);
    }

    public Style(Font font, Background background) {
        super();
        this.font = font;
        this.background = background;
    }

    public Style(Font font, Border border, Background background) {
        super();
        this.font = font;
        this.background = background;
        setBorder(border);
    }

    public Style(Font font, Border border, Background background, Opacity opacity) {
        super();
        this.font = font;
        this.background = background;
        this.opacity = opacity;
        setBorder(border);
    }

    public Style(Border border, Background background) {
        super();
        this.background = background;
        setBorder(border);
    }

    public Style(Border borderLeft, Border borderTop, Border borderRight,
            Border borderBottom) {
        super();
        this.borderLeft = borderLeft;
        this.borderTop = borderTop;
        this.borderRight = borderRight;
        this.borderBottom = borderBottom;
    }

    public StyleListener getListener() {
        return listener;
    }

    public void setListener(StyleListener listener) {
        if (this.listener != listener) {
            StyleListener old = this.listener;
            
            if (old != null){
                this.listener = null;
                old.onStyleDetach(this);
            }
            
            if (listener != null){
                this.listener = listener;
                listener.onStyleAttach(this);                
            }
        }
    }

    public Font getFont() {
        return font;
    }

    public void setFont(Font font) {
        if (!Utils.isEquals(this.font, font)){
            this.font = font;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.FONT, font);
            }
        }
    }

    public Background getBackground() {
        return background;
    }

    public void setBackground(Background background) {
        if (!Utils.isEquals(this.background, background)){
            this.background = background;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.BACKGROUND, background);
            }
        }
    }

    public Opacity getOpacity() {
        return opacity;
    }

    public void setOpacity(Opacity opacity) {
        if (!Utils.isEquals(this.opacity, opacity)){
            this.opacity = opacity;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.OPACITY, opacity);
            }
        }
    }

    public Border getBorderLeft() {
        return borderLeft;
    }

    public void setBorderLeft(Border borderLeft) {
        if (!Utils.isEquals(this.borderLeft, borderLeft)){
            this.borderLeft = borderLeft;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.BORDER_LEFT, borderLeft);
            }
        }
    }

    public Border getBorderTop() {
        return borderTop;
    }

    public void setBorderTop(Border borderTop) {
        if (!Utils.isEquals(this.borderTop, borderTop)){
            this.borderTop = borderTop;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.BORDER_TOP, borderTop);
            }
        }
    }

    public Border getBorderRight() {
        return borderRight;
    }

    public void setBorderRight(Border borderRight) {
        if (!Utils.isEquals(this.borderRight, borderRight)){
            this.borderRight = borderRight;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.BORDER_RIGHT, borderRight);
            }
        }
    }

    public Border getBorderBottom() {
        return borderBottom;
    }

    public void setBorderBottom(Border borderBottom) {
        if (!Utils.isEquals(this.borderBottom, borderBottom)){
            this.borderBottom = borderBottom;
            
            if (listener != null){
                listener.onStyleAttributeChanged(this, StyleAttribute.BORDER_BOTTOM, borderBottom);
            }
        }
    }    
    
    public void setBorder(Border border) {
        setBorderLeft(border);
        setBorderTop(border);
        setBorderRight(border);
        setBorderBottom(border);
    }

    public void copyBorder(Style style) {
        setBorderLeft(style.getBorderLeft());
        setBorderTop(style.getBorderTop());
        setBorderRight(style.getBorderRight());
        setBorderBottom(style.getBorderBottom());
    }

    @Override
    public String toString() {
        StringBuilder value = new StringBuilder();
        value.append("Style[");
        boolean next = false;
        
        if (font != null){
            next = true;
            value.append("font=").append(font);
        }
        if (borderLeft != null){
            if (next){
                value.append(", ");
            } else {
                next = true;
            }
            value.append("borderLeft=").append(borderLeft);
        }
        if (borderTop != null){
            if (next){
                value.append(", ");
            } else {
                next = true;
            }
            value.append("borderTop=").append(borderTop);
        }
        if (borderRight != null){
            if (next){
                value.append(", ");
            } else {
                next = true;
            }
            value.append("borderRight=").append(borderRight);
        }
        if (borderBottom != null){
            if (next){
                value.append(", ");
            } else {
                next = true;
            }
            value.append("borderBottom=").append(borderBottom);
        }
        if (background != null){
            if (next){
                value.append(", ");
            } else {
                next = true;
            }
            value.append("background=").append(background);
        }
        if (opacity != null){
            if (next){
                value.append(", ");
            }
            value.append("opacity=").append(opacity);
        }
        
        value.append(']');
        return value.toString();
    }

    @Override
    public Style clone() {
        try {
            Style c = (Style) super.clone();
            c.listener = null;
            return c;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

}
